/***
 * * PROJECT
 * *    ATaG
 * * VERSION
 * *    $Revision: 1.5 $
 * * DATE
 * *    $Date: 2008/10/07 12:57:36 $
 * * LOG
 * *    $Log: ITaGProgram.java,v $
 * *    Revision 1.5  2008/10/07 12:57:36  animesh
 * *    removed GPL License [will re-add to all files later]
 * *
 * *    Revision 1.4  2007/01/28 21:39:23  animesh
 * *    had forgotten to init the array. Fixed.
 * *
 * *    Revision 1.3  2007/01/15 09:13:23  animesh
 * *    no change.
 * *
 * *    Revision 1.2  2006/12/30 09:36:21  animesh
 * *    Added method to compute the number of copies of a task needed. Still needs to be developed more.
 * *
 * *    Revision 1.1  2006/12/22 00:55:45  animesh
 * *    Added CVS Preamble
 * *
 * *
 * *
 * *
 * *   ATaG (Abstract Task Graph) - Data-driven Macroprogramming for
 * *                                Sensor Networks
 * *
 ***/


package atag.compiler;

import atag.common.*;
import java.util.Set;

/**
 *
 * @author Animesh
 */
public class ITaGProgram {
    
    /** Array to contain the number of copies of each task to be instantiated  */
    int[] numberOfCopiesOfTask;
    
    
    /** Creates a new instance of ITaGProgram */
    public ITaGProgram(ATaGProgram aProgram, NetworkTopology nTopo) {
        this.numberOfCopiesOfTask = new int[aProgram.getTaskList().size()];

        for(ATaGTaskDeclaration atd: aProgram.getTaskList()){
            
            // Handle External Tasks
            if(atd.getFiringRule()[0] == ATaGTaskDeclaration.FIRING_EXTERN)
            {
                this.numberOfCopiesOfTask[atd.getID()] = 0;
                continue;
            }
            
            //TODO complete this with what?

            this.numberOfCopiesOfTask[atd.getID()] =
                    getNumberOfInstantiatedTasks(atd, nTopo);
        }
        
    }
    
    public int numberOfCopiesOfTasks(ATaGTaskDeclaration atd){
        return this.numberOfCopiesOfTask[atd.getID()];
    }
    
    
    private int getNumberOfInstantiatedTasks(ATaGTaskDeclaration t, NetworkTopology nTopo){
        int[] tLocation = t.getLocation();
        
        int retnum = -1;
        
        switch (tLocation[0]){
            case ATaGTaskDeclaration.INSTANTIATION_ONE_ANYWHERE:
                //one anywhere
                retnum = 1;
                break;
            case ATaGTaskDeclaration.INSTANTIATION_ONE_ON_NODE_ID:
                //one on a specific node
                retnum = 1;
                break;
            case ATaGTaskDeclaration.INSTANTIATION_NODES_PER_INSTANCE:
                // see if the instantiation is qualified, and if so, focus on 
                // those nodes only
                if (t.getNeededAttribute() != null){
                    retnum = nTopo.numberOfNodesWithAttribute(t.getNeededAttribute().getKey(), 
                            ((String)((Set)t.getNeededAttribute().getValue()).toArray()[0]))/tLocation[1];
                }else{
                    retnum = nTopo.getNumberOfNodes()/tLocation[1];
                }
                break;
            case ATaGTaskDeclaration.INSTANTIATION_PARTITION_PER_INSTANCE:
                String regionName = t.getMyRegionName();
                retnum = nTopo.numberOfRegions(regionName) * tLocation[1];
                break;
            default:
                System.err.println("Invalid Task Location " + tLocation[0] + "for" +
                        "Task ID" + t.getID());
                System.exit(-3);
                
        }
        return retnum;
    }
    
}
